package com.sc.nft.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.sc.nft.dao.*;
import com.sc.nft.dto.CommonPaymentDTO;
import com.sc.nft.entity.*;
import com.sc.nft.entity.vo.BalanceVO;
import com.sc.nft.entity.vo.ChannelLimitVO;
import com.sc.nft.entity.vo.PaymentMethodVO;
import com.sc.nft.entity.vo.mall.MallPaymentMethodVO;
import com.sc.nft.enums.AccountStatusEnum;
import com.sc.nft.enums.PayMethodEnum;
import com.sc.nft.enums.WalletChannelEnum;
import com.sc.nft.helper.LlPayHelper;
import com.sc.nft.helper.SandAccountHelper;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.MallProductService;
import com.sc.nft.service.PaymentMethodService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class PaymentMethodServiceImpl implements PaymentMethodService {
    private final PaymentMethodDao paymentMethodDao;
    private final UserWalletDao userWalletDao;
    private final SandAccountHelper sandAccountHelper;
    private final StaticDataDao staticDataDao;
    private final UserCityServerCentreDao userCityServerCentreDao;
    private final MallActivityDao mallActivityDao;
    private final MallProductService mallProductService;
    private final LlUserExtDao llUserExtDao;
    private final LlPayHelper llPayHelper;
    private final UserOrderAccountFlowDao userOrderAccountFlowDao;
    private final PaymentScenarioDao paymentScenarioDao;

    @Override
    public List<PaymentMethodVO> getEffectPayment() {
        List<PaymentMethod> effectPayment = paymentMethodDao.getEffectPayment();
        return getPayList(effectPayment, null);
    }

    @Override
    public List<ChannelLimitVO> getChannelLimit() {
        List<PaymentMethod> paymentMethods = paymentMethodDao.listByPayMethod(PayMethodEnum.HNA_PAY, PayMethodEnum.FAST_PAY, PayMethodEnum.HF_FAST_PAY, PayMethodEnum.LL_PAY);
        List<ChannelLimitVO> result = Lists.newArrayList();
        for (PaymentMethod paymentMethod : paymentMethods) {
            ChannelLimitVO channelLimitVO = new ChannelLimitVO();
            switch (paymentMethod.getPayMethod()) {
                case FAST_PAY:
                    channelLimitVO.setChannel(WalletChannelEnum.SAND);
                    break;
                case HF_FAST_PAY:
                    channelLimitVO.setChannel(WalletChannelEnum.HF);
                    break;
                case LL_PAY:
                    channelLimitVO.setChannel(WalletChannelEnum.LL);
                    break;
                case HNA_PAY:
                    channelLimitVO.setChannel(WalletChannelEnum.HNA);
                    break;
            }
            channelLimitVO.setBankList(paymentMethod.getBankList());
            result.add(channelLimitVO);

        }
        return result;
    }

    @Override
    public List<PaymentMethodVO> getEffectPaymentWeb() {
        List<PaymentMethod> effectPayment = paymentMethodDao.getEffectPaymentByIsH5Web();
        return getPayList(effectPayment, null);
    }

    @Override
    public List<PaymentMethodVO> getPaymentMethodSecond() {
        List<PaymentMethod> effectPayment = paymentMethodDao.getSecondEffectPayment();
        return getPayList(effectPayment, null);
    }

    @Override
    public List<PaymentMethodVO> getPaymentMethodsByRecharge(Boolean isH5, UserInfo userInfo) {
        List<PaymentMethod> effectPayment = paymentMethodDao.getPaymentMethodsByRecharge(isH5);
        return getPayList(effectPayment, userInfo);
    }


    @Override
    public List<MallPaymentMethodVO> getMallEffectPayment(Boolean isH5, Long activityId) {
        List<PaymentMethod> effectPayment = paymentMethodDao.getMallEffectPayment(isH5);
        return getIPMallPayList(effectPayment, activityId);
//        return getMallPayList(effectPayment);
    }

    @Override
    public List<MallPaymentMethodVO> getPayMethodsByIsH5(Boolean isH5) {
        List<PaymentMethod> payMethodsByIsH5 = paymentMethodDao.getPayMethodsByIsH5(isH5);
        return getMallPayList(payMethodsByIsH5);
    }

    @Override
    public List<MallPaymentMethodVO> getSecondPayMethods() {
        List<PaymentMethod> payMethods = paymentMethodDao.getSecondEffectPayment();
//        ArrayList<MallPaymentMethodVO> mallPayList = getMallPayList(payMethods);
//        for (MallPaymentMethodVO mallPaymentMethodVO : mallPayList) {
//            //总余额减掉购物金（原石 + 余额）
//            mallPaymentMethodVO.setSumBalance(BigDecimal.valueOf(Long.parseLong(mallPaymentMethodVO.getSumBalance())).subtract(BigDecimal.valueOf(Long.parseLong(mallPaymentMethodVO.getWishBalance()))).stripTrailingZeros().toPlainString());
//        }
        return getMallPayList(payMethods);
    }

    @Override
    public List<MallPaymentMethodVO> getSecondEquityPropsPayment() {
        List<PaymentMethod> payMethods = paymentMethodDao.getSecondEquityPropsPayment();
        return getMallPayList(payMethods);
    }

    @Override
    public List<PaymentMethodVO> getTradingPoolPayMethod() {
        List<PaymentMethod> tradingPoolPayment = paymentMethodDao.getTradingPoolPayment();
        return getPayList(tradingPoolPayment, null);
    }

    @Override
    public List<PaymentMethodVO> commonPaymentMethods(CommonPaymentDTO dto) {
        List<PaymentScenario> paymentScenarios = paymentScenarioDao.listByPayScenario(dto.getPayScenario());
        if (CollectionUtil.isEmpty(paymentScenarios)) {
            return Collections.emptyList();
        }
        List<PayMethodEnum> payMethodEnumList = paymentScenarios.stream().map(PaymentScenario::getPayMethod).distinct().collect(Collectors.toList());
        List<PaymentMethod> paymentMethodList = paymentMethodDao.listByPayMethodParam(payMethodEnumList, dto.getIsH5Pay(), dto.getIsAppPay());
        if (CollectionUtil.isEmpty(paymentMethodList)) {
            return Collections.emptyList();
        }
        return getPayList(paymentMethodList, null);
    }

    private ArrayList<PaymentMethodVO> getPayList(List<PaymentMethod> effectPayment, UserInfo userInfo) {
        ArrayList<PaymentMethodVO> list = Lists.newArrayList();
        for (PaymentMethod paymentMethod : effectPayment) {
            PaymentMethodVO paymentMethodVO = BeanUtil.copyProperties(paymentMethod, PaymentMethodVO.class);
            if (paymentMethod.getPayMethod() == PayMethodEnum.WALLET_PAY) {
                UserInfo user = UserPool.getUser();
                UserWallet byUserId = userWalletDao.getByUserId(user.getId());
                paymentMethodVO.setBalance(byUserId.getBalance().stripTrailingZeros().toPlainString());
                paymentMethodVO.setSumBalance(byUserId.getBalance().add(byUserId.getPayBalance()).stripTrailingZeros().toPlainString());
                paymentMethodVO.setRedEnvelope(byUserId.getPayBalance().stripTrailingZeros().toPlainString());
                paymentMethodVO.setUserTel(user.getUserTel());
            }
            // 只有城市服务中心用户才展示
            if (BeanUtil.isNotEmpty(userInfo)) {
                if (BeanUtil.isNotEmpty(userCityServerCentreDao.getByUserId(userInfo.getId()))) {
                    if (paymentMethod.getPayMethod() == PayMethodEnum.BALANCE_ONLY) {
                        UserInfo user = UserPool.getUser();
                        UserWallet byUserId = userWalletDao.getByUserId(user.getId());
                        paymentMethodVO.setBalance(byUserId.getBalance().stripTrailingZeros().toPlainString());
                        paymentMethodVO.setSumBalance(byUserId.getBalance().stripTrailingZeros().toPlainString());
                        paymentMethodVO.setRedEnvelope(BigDecimal.ZERO.stripTrailingZeros().toPlainString());
                        paymentMethodVO.setUserTel(user.getUserTel());
                    }
                }
            }

            if (paymentMethod.getPayMethod() == PayMethodEnum.SAND_BALANCE_PAY) {
                UserInfo user = UserPool.getUser();
                log.info("获取杉德支付余额获取用户信息数据：{}", JSON.toJSON(user));
                BalanceVO balance = null;
                try {
                    balance = sandAccountHelper.getBalance(user);
                    paymentMethodVO.setBalance(balance.getAvailableBal());
                } catch (Exception e) {
                    paymentMethodVO.setBalance("0");
                }
                paymentMethodVO.setUserTel(user.getUserTel());
                //查询待结算金额
//                ScUserAccountFlow accountFlow = userOrderAccountFlowDao.queryOrInit(user.getId(), PayChannelEnum.SAND);
//                paymentMethodVO.setUnSettleAmount(accountFlow.getUnsettleAmount());
            }
            /**
             * TODO 新增连连钱包支付
             */
            if (paymentMethod.getPayMethod() == PayMethodEnum.LL_BALANCE_PAY) {
                UserInfo user = UserPool.getUser();
                LlUserExt userExt = llUserExtDao.getByUserId(user.getId());
                paymentMethodVO.setBalance("0");
                if (ObjectUtil.isNotNull(userExt) && userExt.getStatus() == AccountStatusEnum.SUCCESS) {
                    JSONObject jsonObject = llPayHelper.getBalance(userExt);
                    paymentMethodVO.setBalance(jsonObject.getBigDecimal("amt_balaval").toString());
                }
                //查询待结算金额
//                ScUserAccountFlow accountFlow = userOrderAccountFlowDao.queryOrInit(user.getId(), PayChannelEnum.LL_PAY);
//                paymentMethodVO.setUnSettleAmount(accountFlow.getUnsettleAmount());
            }
            if (paymentMethod.getPayMethod() == PayMethodEnum.BALANCE_ONLY) {
                if (StrUtil.isNotBlank(paymentMethodVO.getBalance())) {
                    list.add(paymentMethodVO);
                }
            } else {
                list.add(paymentMethodVO);
            }
        }
        return list;
    }

    /**
     * TODO 增加连连钱包
     *
     * @param effectPayment
     * @return
     */
    private ArrayList<MallPaymentMethodVO> getMallPayList(List<PaymentMethod> effectPayment) {
        ArrayList<MallPaymentMethodVO> list = Lists.newArrayList();
        for (PaymentMethod paymentMethod : effectPayment) {
            MallPaymentMethodVO paymentMethodVO = BeanUtil.copyProperties(paymentMethod, MallPaymentMethodVO.class);
            if (paymentMethod.getPayMethod() == PayMethodEnum.WALLET_PAY) {
                UserInfo user = UserPool.getUser();
                UserWallet byUserId = userWalletDao.getByUserId(user.getId());
                paymentMethodVO.setBalance(byUserId.getBalance().stripTrailingZeros().toPlainString());
                paymentMethodVO.setSumBalance(byUserId.getBalance().add(byUserId.getPayBalance()).stripTrailingZeros().toPlainString());
                paymentMethodVO.setWishBalance(byUserId.getWishBalance().stripTrailingZeros().toPlainString());
                paymentMethodVO.setRedEnvelope(byUserId.getPayBalance().stripTrailingZeros().toPlainString());

            }
            if (paymentMethod.getPayMethod() == PayMethodEnum.SAND_BALANCE_PAY) {
                UserInfo user = UserPool.getUser();
                BalanceVO balance = null;
                try {
                    balance = sandAccountHelper.getBalance(user);
                    paymentMethodVO.setBalance(balance.getAvailableBal());
                } catch (Exception e) {
                    paymentMethodVO.setBalance("0");
                }
                //查询待结算金额
//                ScUserAccountFlow accountFlow = userOrderAccountFlowDao.queryOrInit(user.getId(), PayChannelEnum.SAND);
//                paymentMethodVO.setUnSettleAmount(accountFlow.getUnsettleAmount());
            }
            /**
             * TODO 新增连连钱包支付
             */
            if (paymentMethod.getPayMethod() == PayMethodEnum.LL_BALANCE_PAY) {
                UserInfo user = UserPool.getUser();
                LlUserExt userExt = llUserExtDao.getByUserId(user.getId());
                paymentMethodVO.setBalance("0");
                if (ObjectUtil.isNotNull(userExt) && userExt.getStatus() == AccountStatusEnum.SUCCESS) {
                    JSONObject jsonObject = llPayHelper.getBalance(userExt);
                    paymentMethodVO.setBalance(jsonObject.getBigDecimal("amt_balaval").toString());
                }
                //查询待结算金额
//                ScUserAccountFlow accountFlow = userOrderAccountFlowDao.queryOrInit(user.getId(), PayChannelEnum.LL_PAY);
//                paymentMethodVO.setUnSettleAmount(accountFlow.getUnsettleAmount());
            }
            list.add(paymentMethodVO);
        }
        return list;
    }

    private ArrayList<MallPaymentMethodVO> getIPMallPayList(List<PaymentMethod> effectPayment, Long activityId) {
        boolean allowedShoppingCoupons = true;
        if (null != activityId) {
            MallActivity activity = mallActivityDao.getById(activityId);
            MallProduct product = mallProductService.getById(activity.getProductId());
            allowedShoppingCoupons = product.isAllowedShoppingCoupons();
        }

        ArrayList<MallPaymentMethodVO> list = Lists.newArrayList();
        String zoologyActivityIds = staticDataDao.getByType("zoology_activity_ids").getValue();
        List<Long> ids = JSONArray.parseArray(zoologyActivityIds, Long.class);
        for (PaymentMethod paymentMethod : effectPayment) {
            MallPaymentMethodVO paymentMethodVO = BeanUtil.copyProperties(paymentMethod, MallPaymentMethodVO.class);
            if (paymentMethod.getPayMethod() == PayMethodEnum.WALLET_PAY) {
                UserInfo user = UserPool.getUser();
                UserWallet byUserId = userWalletDao.getByUserId(user.getId());
                BigDecimal wishBalance = byUserId.getWishBalance();
                if (ids.contains(activityId) || !allowedShoppingCoupons) {
                    paymentMethodVO.setIsCanUseWishBalance(Boolean.FALSE);
                    wishBalance = BigDecimal.ZERO;
                }
                paymentMethodVO.setBalance(byUserId.getBalance().stripTrailingZeros().toPlainString());
                paymentMethodVO.setSumBalance(byUserId.getBalance().add(byUserId.getPayBalance().add(wishBalance)).stripTrailingZeros().toPlainString());
                paymentMethodVO.setWishBalance(wishBalance.stripTrailingZeros().toPlainString());
                paymentMethodVO.setRedEnvelope(byUserId.getPayBalance().stripTrailingZeros().toPlainString());
            }
            if (paymentMethod.getPayMethod() == PayMethodEnum.SAND_BALANCE_PAY) {
                UserInfo user = UserPool.getUser();
                BalanceVO balance = null;
                try {
                    balance = sandAccountHelper.getBalance(user);
                    paymentMethodVO.setBalance(balance.getAvailableBal());
                } catch (Exception e) {
                    paymentMethodVO.setBalance("0");
                }
            }
            list.add(paymentMethodVO);
        }
        return list;
    }


}



